import { ISvgInfo } from './types'
import { camelCase, pascalCase } from './util'

export interface IGeneratorOptions {
  author: string
  name: string
  nameDisplayType?: 'origin' | 'camel' | 'pascal'
  description?: string
  prefix?: string
}

export class Generator {
  protected author: string
  protected name: string
  protected nameDisplayType: 'origin' | 'camel' | 'pascal'
  protected description: string
  protected result: string = ''
  protected indentSize: number = 0
  protected isNewLine: boolean = true
  protected prefix: string

  constructor(options: IGeneratorOptions) {
    this.name = options.name
    this.author = options.author
    this.nameDisplayType = options.nameDisplayType || 'origin'
    this.description = options.description || ''
    this.prefix = options.prefix || 'icon'
  }

  public process(info: ISvgInfo): string {
    throw new Error('method must be override')
  }

  // 获取处理结果
  protected getResult(): string {
    return this.result
  }

  // 生成顶部注释
  protected processHeaderComment(): void {
    const { name, author, nameDisplayType } = this
    const displayName =
      nameDisplayType === 'pascal'
        ? pascalCase(name)
        : nameDisplayType === 'camel'
        ? camelCase(name)
        : name

    this.writeLine('/**')
    this.writeLine(' * @file ' + displayName + ' ' + this.description)
    this.writeLine(' * @author Auto Generated by ' + author)
    this.writeLine(' */')
    this.writeLine('')
  }

  // 写一个空格
  protected space(): void {
    if (this.isNewLine) {
      this.result += ' '.repeat(this.indentSize * 4)
      this.isNewLine = false
    }

    this.result += ' '
  }

  // 写一行代码
  protected writeLine(word?: string): void {
    if (!word) {
      this.result += '\n'
      this.isNewLine = true
      return
    }
    this.write(word)
    this.result += '\n'
    this.isNewLine = true
  }

  // 写一部分代码
  protected write(word: string): void {
    if (this.isNewLine) {
      this.result += ' '.repeat(this.indentSize * 4)
      this.isNewLine = false
    }
    this.result += word
  }

  // 添加缩进
  protected indent(size: number): void {
    this.indentSize = Math.max(this.indentSize + size, 0)
  }

  protected getInterfaceName(type: string, isSvg: boolean = false): string {
    return 'I' + this.getTypeName(type, isSvg)
  }

  protected getTypeName(type: string, isSvg: boolean = false): string {
    const { prefix } = this
    return `${isSvg ? 'Svg' : ''}${pascalCase(prefix)}${
      type ? pascalCase(type) : ''
    }`
  }
}
